﻿using System;
using System.Collections.Generic;
using System.Windows.Media.Media3D;
using HelixToolkit.Wpf;
using System.Linq;
using System.Windows;

namespace GameBoard
{
    public class MapVisual : ParametricSurface3D, IVisual, ITerrainFeature
    {
        public ModelVisual3D VisualElement
        {
            get { return this; }
        }

        
        protected override Point3D Evaluate(double u, double v, out Point texCoord)
        {
            texCoord = new Point(u, v);
            var curPoint = new Point3D(u * EvaluateWidth, v * EvaluateHeight, 0);
            //double dist2 = PointSet.Sum(cur => Math.Cos(curPoint.DistanceTo(cur) * Multiplier + Math.Sin(curPoint.DistanceTo(cur) * Multiplier)));
            var info = SimplexNoise.Generate((float)u, (float)v, 0) * HillValue;
            var newP = new Point3D(curPoint.X, curPoint.Y, info);
            return newP;
        }
        bool _belongsToMoveablePicture = false;
        public bool BelongsToMoveablePicture
        {
            get { return _belongsToMoveablePicture; }
        }
        public bool IsSolid
        {
            get { return true; }
            set { }
        }

        public Guid FactoryID { get; set; }

        public static double EvaluateHeight { get; set; }
        public static double EvaluateWidth { get; set; }
        public static double HillValue { get; set; }

        public void PopulateVisualData(BaseVisualData theData)
        {
            _belongsToMoveablePicture = theData.BelongsToMoveablePicture;
            FactoryID = theData.FactoryID;

            var mapData = theData as MapVisualData;
            this.Material = mapData.FrontMaterial;
            this.BackMaterial = mapData.BackMaterial;
            Transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(-1, 0, 0), 180), new Point3D(EvaluateWidth / 2, EvaluateHeight / 2, 0));
        }


        private ModelVisual3D MeshToVisual3D(MeshBuilder mb, Material theMaterial,
            Material backMaterial = null)
        {
            var myModelVisual3D = new ModelVisual3D();
            var theModel = new GeometryModel3D(mb.ToMesh(), theMaterial);
            if (backMaterial == null)
            {
                backMaterial = theMaterial;
            }
            else
            {
                theModel.BackMaterial = backMaterial;
            }
            myModelVisual3D.Content = theModel;
            return myModelVisual3D;
        }


        private MeshBuilder InitializeBoardBoundaries(double height, double width)
        {
            var board = new List<Point3D>();
            board.Add(new Point3D(-width/2, -height/2, 0));

            board.Add(new Point3D(width/2, -height/2, 0));

            board.Add(new Point3D(width/2, height/2, 0));
            board.Add(new Point3D(-width/2, height/2, 0));


            var mb = new MeshBuilder();

            mb.AddQuad(board[0], board[1], board[2], board[3]);
            //mb.AddQuad(board[2], board[0], board[1], board[3]);
            return mb;
        }
    }
}